#include "FaultCheck.h"
#include "DataBase.h"
#include "timer.h"

#define CNT_FLAG_UP 1
#define CNT_FLAG_DOWE 0
#define STATE_ON 1
#define STATE_OFF 0

static u16 OVolt_check_cnt[3] = {0};
static u16 UVolt_check_cnt[3] = {0};
static u16 OCurr_check_cnt[3] = {0};
static u16 UCurr_check_cnt[3] = {0};
static u16 OTemp_check_cnt[3] = {0};
static u16 UTemp_check_cnt[3] = {0};
static u16 OTotal_check_cnt[2] = {0};
static u16 UTotal_check_cnt[2] = {0};
static u16 Diff_Total_check_cnt[1] = {0};
static u16 Diff_Cell_check_cnt[1] = {0};
static u16 Diff_Temp_check_cnt[1] = {0};
static u16 feed_curr_check_cnt[1] = {0};
static u16 ohm_orest_check_cnt[1] = {0};

static void State_OVolt_Check(void);
static void State_UVolt_Check(void);
static void State_OCurr_Check(void);
static void State_UCurr_Check(void);
static void State_OTemp_Check(void);
static void State_UTemp_Check(void);
static void State_Line_OUvolt_Check(void);
static void State_Totol_Diffe_Check(void);
static void State_Cell_Diffe_Check(void);
static void State_Temp_Diffe_Check(void);
static void State_Feed_Curr_Check(void);
static void State_Ohm_Orest_Check(void);

static void Fuault_Flag_Check_L1(void);
static void Fuault_Flag_Check_L2(void);
static void Fuault_Flag_Check_L3(void);

u8 Fault_State_Check(void)
{
	if (gTime100ms_FlagA != ON)
	{
		return gRET_NG;
	}
	State_OVolt_Check();
	State_UVolt_Check();
	State_OCurr_Check();
	State_UCurr_Check();
	State_OTemp_Check();
	State_UTemp_Check();

	State_Line_OUvolt_Check();
	State_Totol_Diffe_Check();
	State_Cell_Diffe_Check();
	State_Temp_Diffe_Check();
	State_Feed_Curr_Check();
	State_Ohm_Orest_Check();

	Fuault_Flag_Check_L1();
	Fuault_Flag_Check_L2();
	Fuault_Flag_Check_L3();
	return gRET_OK;
}

static u8 Faul_Base_CheckUN(u32 value_HP, u32 value_LP, u32 value_real, u8 state_last, u8 flag_UD)
{
	u8 ret = 0;

	if (flag_UD == CNT_FLAG_UP)
	{
		if (value_real >= value_HP)
		{
			ret = STATE_ON;
		}
		else if (value_real <= value_LP)
		{
			ret = STATE_OFF;
		}
		else
		{
			ret = state_last;
		}
	}
	else if (flag_UD == CNT_FLAG_DOWE)
	{
		if (value_real <= value_HP)
		{
			ret = STATE_ON;
		}
		else if (value_real >= value_LP)
		{
			ret = STATE_OFF;
		}
		else
		{
			ret = state_last;
		}
	}
	return ret;
}

static u8 Faul_Base_CheckIN(i32 value_HP, i32 value_LP, i32 value_real, u8 state_last, u8 flag_UD)
{
	u8 ret = 0;

	if (flag_UD == CNT_FLAG_UP)
	{
		if (value_real >= value_HP)
		{
			ret = STATE_ON;
		}
		else if (value_real <= value_LP)
		{
			ret = STATE_OFF;
		}
		else
		{
			ret = state_last;
		}
	}
	else if (flag_UD == CNT_FLAG_DOWE)
	{
		if (value_real <= value_HP)
		{
			ret = STATE_ON;
		}
		else if (value_real >= value_LP)
		{
			ret = STATE_OFF;
		}
		else
		{
			ret = state_last;
		}
	}
	return ret;
}

static void State_OVolt_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_OVOLT_STATE & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfOVOLT_HP1, cfOVOLT_LP1, gCELL_VOLT_MAX, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OVolt_check_cnt[0]++ >= cf0VOLT_TIME_LP1)
		{
			if (status_real == ON)
			{
				gFUAULT_OVOLT_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_OVOLT_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		OVolt_check_cnt[0] = 0;
	}

	if (gFUAULT_OVOLT_STATE & 0x02)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfOVOLT_HP2, cfOVOLT_LP2, gCELL_VOLT_MAX, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OVolt_check_cnt[1]++ >= cf0VOLT_TIME_LP2)
		{
			if (status_real == ON)
			{
				gFUAULT_OVOLT_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_OVOLT_STATE &= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		OVolt_check_cnt[1] = 0;
	}

	if (gFUAULT_OVOLT_STATE & 0x04)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfOVOLT_HP3, cfOVOLT_LP3, gCELL_VOLT_MAX, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OVolt_check_cnt[2]++ >= cf0VOLT_TIME_LP3)
		{
			if (status_real == ON)
			{
				gFUAULT_OVOLT_STATE |= (STATE_ON << 2);
			}
			else
			{
				gFUAULT_OVOLT_STATE &= ~(STATE_OFF << 2);
			}
		}
	}
	else
	{
		OVolt_check_cnt[2] = 0;
	}
}

static void State_UVolt_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_UVOLT_STATE & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfUVOLT_HP1, cfUVOLT_LP1, gCELL_VOLT_MIN, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UVolt_check_cnt[0]++ >= cfUVOLT_TIME_LP1)
		{
			if (status_real == ON)
			{
				gFUAULT_UVOLT_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_UVOLT_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		UVolt_check_cnt[0] = 0;
	}

	if (gFUAULT_UVOLT_STATE & 0x02)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfUVOLT_HP2, cfUVOLT_LP2, gCELL_VOLT_MIN, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UVolt_check_cnt[1]++ >= cfUVOLT_TIME_LP2)
		{
			if (status_real == ON)
			{
				gFUAULT_UVOLT_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_UVOLT_STATE &= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		UVolt_check_cnt[1] = 0;
	}

	if (gFUAULT_UVOLT_STATE & 0x04)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfUVOLT_HP3, cfUVOLT_LP3, gCELL_VOLT_MIN, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UVolt_check_cnt[2]++ >= cfUVOLT_TIME_LP3)
		{
			if (status_real == ON)
			{
				gFUAULT_UVOLT_STATE |= (STATE_ON << 2);
			}
			else
			{
				gFUAULT_UVOLT_STATE &= ~(STATE_OFF << 2);
			}
		}
	}
	else
	{
		UVolt_check_cnt[2] = 0;
	}
}

static void State_OCurr_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_OCURR_STATE & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfOCURR_HP1, cfOCURR_LP1, gCURR_LINE, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OCurr_check_cnt[0]++ >= cfOCURR_TIME_LP1)
		{
			if (status_real == ON)
			{
				gFUAULT_OCURR_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_OCURR_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		OCurr_check_cnt[0] = 0;
	}

	if (gFUAULT_OCURR_STATE & 0x02)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfOCURR_HP2, cfOCURR_LP2, gCURR_LINE, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OCurr_check_cnt[1]++ >= cfOCURR_TIME_LP2)
		{
			if (status_real == ON)
			{
				gFUAULT_OCURR_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_OCURR_STATE &= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		OCurr_check_cnt[1] = 0;
	}

	if (gFUAULT_OCURR_STATE & 0x04)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfOCURR_HP3, cfOCURR_LP3, gCURR_LINE, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OCurr_check_cnt[2]++ >= cfOCURR_TIME_LP3)
		{
			if (status_real == ON)
			{
				gFUAULT_OCURR_STATE |= (STATE_ON << 2);
			}
			else
			{
				gFUAULT_OCURR_STATE &= ~(STATE_OFF << 2);
			}
		}
	}
	else
	{
		OCurr_check_cnt[2] = 0;
	}
}

static void State_UCurr_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_UCURR_STATE & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfUCURR_HP1, cfUCURR_LP1, gCURR_LINE, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UCurr_check_cnt[0]++ >= cfUCURR_TIME_LP1)
		{
			if (status_real == ON)
			{
				gFUAULT_UCURR_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_UCURR_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		UCurr_check_cnt[0] = 0;
	}

	if (gFUAULT_UCURR_STATE & 0x02)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfUCURR_HP2, cfUCURR_LP2, gCURR_LINE, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UCurr_check_cnt[1]++ >= cfUCURR_TIME_LP2)
		{
			if (status_real == ON)
			{
				gFUAULT_UCURR_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_UCURR_STATE &= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		UCurr_check_cnt[1] = 0;
	}

	if (gFUAULT_UCURR_STATE & 0x04)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfUCURR_HP3, cfUCURR_LP3, gCURR_LINE, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UCurr_check_cnt[2]++ >= cfUCURR_TIME_LP3)
		{
			if (status_real == ON)
			{
				gFUAULT_UCURR_STATE |= (STATE_ON << 2);
			}
			else
			{
				gFUAULT_UCURR_STATE &= ~(STATE_OFF << 2);
			}
		}
	}
	else
	{
		UCurr_check_cnt[2] = 0;
	}
}

static void State_OTemp_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_OTEMP_STATE & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfOTEMP_HP1, cfOTEMP_LP1, gTEMP_PACK_MAX, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OTemp_check_cnt[0]++ >= cfOTEMP_TIME_LP1)
		{
			if (status_real == ON)
			{
				gFUAULT_OTEMP_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_OTEMP_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		OTemp_check_cnt[0] = 0;
	}

	if (gFUAULT_OTEMP_STATE & 0x02)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfOTEMP_HP2, cfOTEMP_LP2, gTEMP_PACK_MAX, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OTemp_check_cnt[1]++ >= cfOTEMP_TIME_LP2)
		{
			if (status_real == ON)
			{
				gFUAULT_OTEMP_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_OTEMP_STATE &= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		OTemp_check_cnt[1] = 0;
	}

	if (gFUAULT_OTEMP_STATE & 0x04)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfOTEMP_HP3, cfOTEMP_LP3, gTEMP_PACK_MAX, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OTemp_check_cnt[2]++ >= cfOTEMP_TIME_LP3)
		{
			if (status_real == ON)
			{
				gFUAULT_OTEMP_STATE |= (STATE_ON << 2);
			}
			else
			{
				gFUAULT_OTEMP_STATE &= ~(STATE_OFF << 2);
			}
		}
	}
	else
	{
		OTemp_check_cnt[2] = 0;
	}
}

static void State_UTemp_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_UTEMP_STATE & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfUTEMP_HP1, cfUTEMP_LP1, gTEMP_PACK_MIN, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UTemp_check_cnt[0]++ >= cfUTEMP_TIME_LP1)
		{
			if (status_real == ON)
			{
				gFUAULT_UTEMP_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_UTEMP_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		UTemp_check_cnt[0] = 0;
	}

	if (gFUAULT_UTEMP_STATE & 0x02)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfUTEMP_HP2, cfUTEMP_LP2, gTEMP_PACK_MIN, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UTemp_check_cnt[1]++ >= cfUTEMP_TIME_LP2)
		{
			if (status_real == ON)
			{
				gFUAULT_UTEMP_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_UTEMP_STATE &= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		UTemp_check_cnt[1] = 0;
	}

	if (gFUAULT_UTEMP_STATE & 0x04)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfUTEMP_HP3, cfUTEMP_LP3, gTEMP_PACK_MIN, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UTemp_check_cnt[2]++ >= cfUTEMP_TIME_LP3)
		{
			if (status_real == ON)
			{
				gFUAULT_UTEMP_STATE |= (STATE_ON << 2);
			}
			else
			{
				gFUAULT_UTEMP_STATE &= ~(STATE_OFF << 2);
			}
		}
	}
	else
	{
		UTemp_check_cnt[2] = 0;
	}
}

static void State_Line_OUvolt_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_OLINE_STATE & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfOVOLT_LINE_HP1, cfOVOLT_LINE_LP1, gVOLT_LINE, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OTotal_check_cnt[0]++ >= cfOVOLT_LINE_TIME_HP1)
		{
			if (status_real == ON)
			{
				gFUAULT_OLINE_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_OLINE_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		OTotal_check_cnt[0] = 0;
	}

	if (gFUAULT_OLINE_STATE & 0x02)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfOVOLT_LINE_HP2, cfOVOLT_LINE_PP2, gVOLT_LINE, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (OTotal_check_cnt[1]++ >= cfOVOLT_LINE_TIME_HP2)
		{
			if (status_real == ON)
			{
				gFUAULT_OLINE_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_OLINE_STATE &= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		OTotal_check_cnt[1] = 0;
	}

	if (gFUAULT_ULINE_STATE & 0x10)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfUVOLT_LINE_HP1, cfUVOLT_LINE_LP1, gVOLT_LINE, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UTotal_check_cnt[0]++ >= cfOVOLT_LINE_TIME_HP1)
		{
			if (status_real == ON)
			{
				gFUAULT_ULINE_STATE |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_ULINE_STATE |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		UTotal_check_cnt[0] = 0;
	}

	if (gFUAULT_ULINE_STATE & 0x20)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfUVOLT_LINE_HP2, cfUVOLT_LINE_LP2, gVOLT_LINE, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (UTotal_check_cnt[1]++ >= cfUVOLT_LINE_TIME_HP2)
		{
			if (status_real == ON)
			{
				gFUAULT_ULINE_STATE |= (STATE_ON << 1);
			}
			else
			{
				gFUAULT_ULINE_STATE |= ~(STATE_OFF << 1);
			}
		}
	}
	else
	{
		UTotal_check_cnt[1] = 0;
	}
}

static void State_Totol_Diffe_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;
	u32 diff_volt = 0;

	if (gVOLT_LINE >= gVOLT_TOTAL)
	{
		diff_volt = gVOLT_LINE - gVOLT_TOTAL;
	}
	else
	{
		diff_volt = gVOLT_TOTAL - gVOLT_LINE;
	}

	if (gFUAULT_TOTAL_DIFF & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfTOTAL_DIFFEVOLT_HP1, cfTOTAL_DIFFEVOLT_LP1, diff_volt, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (Diff_Total_check_cnt[0]++ >= cfTOTAL_DIFFEVOLT_TIME_HP1)
		{
			if (status_real == ON)
			{
				gFUAULT_TOTAL_DIFF |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_TOTAL_DIFF |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		Diff_Total_check_cnt[0] = 0;
	}
}

static void State_Cell_Diffe_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_CELL_DIFF & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfCELL_DIFFEVOLT_HP1, cfCELL_DIFFEVOLT_LP1, gCELL_VOLT_DIFF, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (Diff_Cell_check_cnt[0]++ >= cfCELL_DIFFEVOLT_TIME_HP1)
		{
			if (status_real == ON)
			{
				gFUAULT_CELL_DIFF |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_CELL_DIFF |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		Diff_Cell_check_cnt[0] = 0;
	}
}

static void State_Temp_Diffe_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_TEMP_DIFF & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfTEMP_DIFFE_HP1, cfTEMP_DIFFE_LP1, gTEMP_PACK_DIFF, status_last, CNT_FLAG_UP);
	if (status_real != status_last)
	{
		if (Diff_Temp_check_cnt[0]++ >= cfTEMP_DIFFE_TIME_HP1)
		{
			if (status_real == ON)
			{
				gFUAULT_TEMP_DIFF |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_TEMP_DIFF |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		Diff_Temp_check_cnt[0] = 0;
	}
}

static void State_Feed_Curr_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_FEED_BACK & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckIN(cfFEEDBACK_OCURR_HP1, cfFEEDBACK_OCURR_LP1, 0, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (feed_curr_check_cnt[0]++ >= cfFEEDBACK_OCURR_TIME_HP1)
		{
			if (status_real == ON)
			{
				gFUAULT_FEED_BACK |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_FEED_BACK |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		feed_curr_check_cnt[0] = 0;
	}
}

static void State_Ohm_Orest_Check(void)
{
	static u8 status_last = 0;
	static u8 status_real = 0;

	if (gFUAULT_OHM_ORESI & 0x01)
	{
		status_last = STATE_ON;
	}
	else
	{
		status_last = STATE_OFF;
	}
	status_real = Faul_Base_CheckUN(cfOHM_ORESI_HP1, cfOHM_ORESI_LP1, 8000, status_last, CNT_FLAG_DOWE);
	if (status_real != status_last)
	{
		if (ohm_orest_check_cnt[0]++ >= cfOHM_ORESI_TIME_HP1)
		{
			if (status_real == ON)
			{
				gFUAULT_OHM_ORESI |= (STATE_ON << 0);
			}
			else
			{
				gFUAULT_OHM_ORESI |= ~(STATE_OFF << 0);
			}
		}
	}
	else
	{
		ohm_orest_check_cnt[0] = 0;
	}
}

static void Fuault_Flag_Check_L1(void)
{
	gFUAULT_FLAG_L1 &= ~(0x03 << FAULT_BIT_Uart2);
	gFUAULT_FLAG_L1 |= ((gFUAULT_UART_COMM & 0x03) << FAULT_BIT_Uart2);

	gFUAULT_FLAG_L1 &= ~(0x03 << FAULT_BITe_Can1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_CAN_COMM & 0x03) << FAULT_BITe_Can1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_EEprom);
	gFUAULT_FLAG_L1 |= ((gFUAULT_EEP_GET & 0x03) << FAULT_BIT_EEprom);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_DSG_Rly);
	gFUAULT_FLAG_L1 |= ((gFUAULT_RLY_CHECK & 0x03) << FAULT_BIT_DSG_Rly);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_CHG_Rly);
	gFUAULT_FLAG_L1 |= ((gFUAULT_CHG & 0x03) << FAULT_BIT_CHG_Rly);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_OVolt_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_OVOLT_STATE & 0x01) << FAULT_BIT_OVolt_HP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_UVolt_LP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_UVOLT_STATE & 0x01) << FAULT_BIT_UVolt_LP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_OCurr_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_OCURR_STATE & 0x01) << FAULT_BIT_OCurr_HP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_UCurr_LP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_UCURR_STATE & 0x01) << FAULT_BIT_UCurr_LP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_OTemp_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_OTEMP_STATE & 0x01) << FAULT_BIT_OTemp_HP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_UTemp_LP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_UTEMP_STATE & 0x01) << FAULT_BIT_UTemp_LP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_OV_Line_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_OLINE_STATE & 0x01) << FAULT_BIT_OV_Line_HP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_UV_Line_LP1);
	gFUAULT_FLAG_L1 |= (((gFUAULT_ULINE_STATE >> 4) & 0x01) << FAULT_BIT_UV_Line_LP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_DiffeV_Total_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_TOTAL_DIFF & 0x01) << FAULT_BIT_DiffeV_Total_HP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_DiffeV_Cell_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_CELL_DIFF & 0x01) << FAULT_BIT_DiffeV_Cell_HP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_DiffeV_Temp_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_TEMP_DIFF & 0x01) << FAULT_BIT_DiffeV_Temp_HP1);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_Feedback_OC_HP1);
	gFUAULT_FLAG_L1 |= ((gFUAULT_FEED_BACK & 0x01) << FAULT_BIT_Feedback_OC_HP1);
}

static void Fuault_Flag_Check_L2(void)
{
	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_Ltc_Init);
	gFUAULT_FLAG_L2 |= ((gFUAULT_LTC_INIT & 0x01) << FAULT_BIT_Ltc_Init);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_Open_line);
	gFUAULT_FLAG_L2 |= ((gFUAULT_LTC_OPEN_LINE & 0x01) << FAULT_BIT_Open_line);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_Cs5463_Init);
	gFUAULT_FLAG_L2 |= ((gFUAULT_CSXX_INIT & 0x01) << FAULT_BIT_Cs5463_Init);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_CHG_ERR);
	gFUAULT_FLAG_L2 |= ((gFUAULT_CHG & 0x01) << FAULT_BIT_CHG_ERR);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_HEAT_ERR);
	gFUAULT_FLAG_L2 |= ((gFUAULT_HEAT & 0x01) << FAULT_BIT_HEAT_ERR);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_OVolt_HP2);
	gFUAULT_FLAG_L2 |= (((gFUAULT_OVOLT_STATE >> 1) & 0x01) << FAULT_BIT_OVolt_HP2);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_UVolt_LP2);
	gFUAULT_FLAG_L2 |= (((gFUAULT_UVOLT_STATE >> 1) & 0x01) << FAULT_BIT_UVolt_LP2);

	gFUAULT_FLAG_L1 &= ~(0x01 << FAULT_BIT_OCurr_HP2);
	gFUAULT_FLAG_L1 |= (((gFUAULT_OCURR_STATE >> 1) & 0x01) << FAULT_BIT_OCurr_HP2);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_UCurr_LP2);
	gFUAULT_FLAG_L2 |= (((gFUAULT_UCURR_STATE >> 1) & 0x01) << FAULT_BIT_UCurr_LP2);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_OTemp_HP2);
	gFUAULT_FLAG_L2 |= (((gFUAULT_OTEMP_STATE >> 1) & 0x01) << FAULT_BIT_OTemp_HP2);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_UTemp_LP1);
	gFUAULT_FLAG_L2 |= (((gFUAULT_UTEMP_STATE >> 1) & 0x01) << FAULT_BIT_UTemp_LP2);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_OV_Line_HP2);
	gFUAULT_FLAG_L2 |= (((gFUAULT_OLINE_STATE >> 1) & 0x01) << FAULT_BIT_OV_Line_HP2);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_UV_Line_LP2);
	gFUAULT_FLAG_L2 |= (((gFUAULT_ULINE_STATE >> 5) & 0x01) << FAULT_BIT_UV_Line_LP2);

	gFUAULT_FLAG_L2 &= ~(0x01 << FAULT_BIT_OHM_OResi_HP1);
	gFUAULT_FLAG_L2 |= (((gFUAULT_OHM_ORESI >> 1) & 0x01) << FAULT_BIT_OHM_OResi_HP1);
}

static void Fuault_Flag_Check_L3(void)
{
	gFUAULT_FLAG_L3 &= ~(0x01 << FAULT_BIT_OVolt_HP3);
	gFUAULT_FLAG_L3 |= (((gFUAULT_OVOLT_STATE >> 2) & 0x01) << FAULT_BIT_OVolt_HP3);

	gFUAULT_FLAG_L3 &= ~(0x01 << FAULT_BIT_UVolt_LP3);
	gFUAULT_FLAG_L3 |= (((gFUAULT_UVOLT_STATE >> 2) & 0x01) << FAULT_BIT_UVolt_LP3);

	gFUAULT_FLAG_L3 &= ~(0x01 << FAULT_BIT_OCurr_HP3);
	gFUAULT_FLAG_L3 |= (((gFUAULT_OCURR_STATE >> 2) & 0x01) << FAULT_BIT_OCurr_HP3);

	gFUAULT_FLAG_L3 &= ~(0x01 << FAULT_BIT_UCurr_LP3);
	gFUAULT_FLAG_L3 |= (((gFUAULT_UCURR_STATE >> 2) & 0x01) << FAULT_BIT_UCurr_LP3);

	gFUAULT_FLAG_L3 &= ~(0x01 << FAULT_BIT_OTemp_HP3);
	gFUAULT_FLAG_L3 |= (((gFUAULT_OTEMP_STATE >> 2) & 0x01) << FAULT_BIT_OTemp_HP3);

	gFUAULT_FLAG_L3 &= ~(0x01 << FAULT_BIT_UTemp_LP3);
	gFUAULT_FLAG_L3 |= (((gFUAULT_UTEMP_STATE >> 2) & 0x01) << FAULT_BIT_UTemp_LP3);
}
